package gates;

import java.awt.Graphics;
import master.*;

/**
 * Implementation of a Simple Quantum Adder
 * composite gate build out of a Toffoli Gate and CNot gate.
 * Can act on a Register forwards of backwards with call to the appropriate methods
 *
 * 
 * @author Oliver
 * 
 */
public class QuantumAdder extends QuantumGate{
	
	int control1,control2,target;
	QuantumGate tGate, cNGate;
	
	/**
	 * creates the two subgates upon call and gives them the qBits to act on
	 * @param control1 
	 * @param control2
	 * @param target
	 */
	public QuantumAdder(int control1, int control2, int target){
		this.control1 = control1;
		this.control2 = control2;
		this.target = target;
		
		tGate = new ToffoliGate(control1,control2,target);
		cNGate = new Cnot(control1, control2);
		
		
	}

	/**
	 * acts with this gate on the given Quantum Register
	 * @param register
	 */
	public void actOnReg(QuantumRegister register) {
		tGate.actOnReg(register);
		//printOut(register);
	
		cNGate.actOnReg(register);
		//printOut(register);
	
	}
	/**
	 * acts with this gate in reverse on the given QuantumGate
	 * @param register
	 */
	public void actOnRegReverse(QuantumRegister register){
		cNGate.actOnReg(register);
		//printOut(register);
		tGate.actOnReg(register);
		//printOut(register);
	}

	/**
	 * used for visual representation of the gate in the UI
	 */

	
	/**
	 * Returns a list with all the qBits the register acts on
	 */
	public int[] getActingBits() {
		int[] actingBits = new int[3];
		actingBits[0]= control1;
		actingBits[1]= control2;
		actingBits[2]= target;
		return actingBits;
	}
	
	/**
	 * prints out the register as states with coefficients
	 * used only for testing
	 * @param reg
	 */
	public static void printOut(QuantumRegister reg){
		for (int n=0;n<reg.getDimension();n++){
			if(reg.getCoefficient(n).magnitudeFloat()>0)
				System.out.println(" " + reg.getCoefficient(n) + "|" + Integer.toBinaryString(n) + "("+ n +")>");
		}
		System.out.println("");
	}
	
	/**
	 * code snippet used to test the gate
	 */
	public static void main(String[] args){
		QuantumRegister reg = new QuantumRegister(3);
		QuantumGate addGate = new QuantumAdder(1, 2, 3);
		reg.setToEigenstate(3);
		
		printOut(reg);
		addGate.actOnReg(reg);
		printOut(reg);
	}

	


}
